﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

namespace AB.Common
{
    /// <summary>
    /// 对象属性值复制
    /// </summary>
    public class ObjectCopy
    {
        /// <summary>
        /// 属性映射
        /// </summary>
        public static Dictionary<string, List<string>> MapDic = new Dictionary<string, List<string>>();
        /// <summary>
        /// S复制到D
        /// </summary>
        /// <typeparam name="D"></typeparam>
        /// <typeparam name="S"></typeparam>
        /// <param name="s"></param>
        /// <param name="emodel">D中存储S的属性名称,默认指定“Emodel”</param>
        /// <returns></returns>
        public static D Copy<D, S>(S s,string emodel= "Emodel")
        {
            if (s == null)
            {
                return default(D);
            }
            D d = Activator.CreateInstance<D>();
            try
            {
                var sType = s.GetType();
                var dType = typeof(D);

                string classname = dType.FullName + "_" + sType.FullName;
                if (MapDic.ContainsKey(classname))
                {
                    foreach (var item in MapDic[classname])
                    {
                        dType.GetProperty(item).SetValue(d, sType.GetProperty(item).GetValue(s));
                    }

                }
                else
                {
                    MapDic.Add(classname, new List<string>());
                    Dictionary<string, TypeAndValue> dic = new Dictionary<string, TypeAndValue>();
                    foreach (PropertyInfo sP in sType.GetProperties())
                    {
                        dic.Add(sP.Name, new TypeAndValue() { type = sP.PropertyType, value = sP.GetValue(s) });
                    }
                    foreach (PropertyInfo dP in dType.GetProperties())
                    {
                        if (dic.ContainsKey(dP.Name))
                        {
                            if (dP.PropertyType == dic[dP.Name].type)
                            {
                                MapDic[classname].Add(dP.Name);
                                dP.SetValue(d, dic[dP.Name].value);
                            }
                        }
                    }
                }
                if (!string.IsNullOrEmpty(emodel))
                {
                    PropertyInfo Emodel = dType.GetProperty(emodel);
                    if (Emodel != null)
                    {
                        if (Emodel.PropertyType == sType)
                        {
                            Emodel.SetValue(d, s);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.Write(ex);
            }
            return d;
        }
        /// <summary>
        /// SList复制到DList
        /// </summary>
        /// <typeparam name="D"></typeparam>
        /// <typeparam name="S"></typeparam>
        /// <param name="sList"></param>
        /// <param name="emodel">D中存储S的属性名称,默认指定“Emodel”</param>
        /// <returns></returns>
        public static IQueryable<D> Copy<D, S>(IQueryable<S> sList, string emodel = "Emodel")
        {
            List<D> dList = new List<D>();
            foreach (var item in sList)
            {
                dList.Add(Copy<D, S>(item,emodel));
            }
            return dList.AsQueryable();
        }
    }
    /// <summary>
    /// 类型和值
    /// </summary>
    class TypeAndValue
    {
        /// <summary>
        /// 类型
        /// </summary>
        public Type type { get; set; }
        /// <summary>
        /// 值
        /// </summary>
        public object value { get; set; }
    }
}
